package com.codimiracle.tools.outline2excel;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.PropertyTemplate;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Deque;
import java.util.LinkedList;
import java.util.Objects;

public class ExcelGenerator {
    private HSSFSheet sheet1;
    private HSSFWorkbook workbook;
    private int rowCount = 0;
    private Deque<MergeFrame> frames = new LinkedList<>();
    private int lastLevel = 0;
    private int maxCol;
    private int maxRow;

    public ExcelGenerator() {
        workbook = new HSSFWorkbook();
        sheet1 = workbook.createSheet("sheet1");
    }

    public void addRow(int level, String title) {
        if (this.maxCol < level) {
            this.maxCol = level;
        }
        // 对齐上一级
        if (level > this.lastLevel) {
            this.rowCount--;
        }

        // 处理当前行
        int current = rowCount++;
        // 更新最大行
        this.maxRow = current;
        HSSFRow row = sheet1.getRow(current);
        if (Objects.isNull(row)) {
            row = sheet1.createRow(current);
        }
        // 创建单元格
        HSSFCell cell = row.createCell(level);
        sheet1.autoSizeColumn(level);
        CellStyle style = workbook.createCellStyle();
        style.setAlignment(HorizontalAlignment.CENTER);
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        cell.setCellStyle(style);

        cell.setCellValue(title);

        this.lastLevel = level;
    }

    /**
     * 开始合并单元格
     *
     * @param level 大纲级别
     */
    public void mergeBegin(int level) {
        MergeFrame frame = new MergeFrame();
        frame.startRow = rowCount - 1;
        frame.level = level;
        frames.push(frame);
    }

    /**
     * 结束合并单元格
     */
    public void mergeEnd() {
        MergeFrame frame = frames.pop();
        frame.endRow = this.rowCount - 1;
        if (frame.endRow - frame.startRow + 1 < 2) {
            return;
        }
        CellRangeAddress cellRangeAddress = new CellRangeAddress(frame.startRow, frame.endRow, frame.level, frame.level);
        sheet1.addMergedRegion(cellRangeAddress);
    }

    public void filBorder() {
        CellRangeAddress cellRangeAddress = new CellRangeAddress(0, this.maxRow, 0, this.maxCol);
        PropertyTemplate pt = new PropertyTemplate();
        pt.drawBorders(cellRangeAddress, BorderStyle.THIN, BorderExtent.ALL);
        pt.applyBorders(sheet1);
    }

    /**
     * 导出 Excel 文件
     *
     * @param filename excel 文件名
     * @throws IOException io 处理失败
     */
    public void export(String filename) throws IOException {
        try (OutputStream fileOut = new FileOutputStream(filename)) {
            workbook.write(fileOut);
            System.out.println("output:" + filename);
        }
    }

    // 合并帧
    static class MergeFrame {
        int startRow;
        int endRow;
        int level;
    }
}
